﻿using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using EncryptHelper;
using WebHelper.Helpers;

namespace WebHelper.Modules
{
    [Serializable]
    internal class EncryptQueryStringFilter : MemoryStream
    {
        private static Regex urlMatch = new Regex("(action|href|src)=[\"']?([^\"'>]*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        private Stream outputStream;
        public EncryptQueryStringFilter(Stream baseStream)
        {
            outputStream = baseStream;
        }

        private string QueryStringMatchEvaluator(Match match)
        {
            string s = match.Value;
            try
            {
                if (!string.IsNullOrEmpty(match.Value) && match.Value.IndexOf('?') != -1)
                {
                    if (UrlHelper.IsInternalUri(UrlHelper.GetCompleteUri(match.Value.Substring(match.Value.IndexOf("=")+2))))
                    {
                        SecurityModule custSection = (SecurityModule)ConfigurationManager.GetSection(typeof(SecurityModule).Name);
                        string queryString = match.Value.Substring(match.Value.IndexOf('?') + 1);
                        string newData = HttpUtility.UrlEncode(DefaultEncryptHelper.Encrypt(queryString, WebHelper.Properties.Resources.Key));
                        string encryptedQueryString = custSection.QueryStringName + "=" + newData.Length + "N" + newData;
                        s = match.Value.Replace(queryString, encryptedQueryString);

                        //trace
                        Trace.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "EncryptQueryString :" + queryString + "------>" + encryptedQueryString, typeof(SecurityModule).Name + "  ");
                    }
                }
            }
            catch
            {
            }
            return s;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            // Get the HTML from the buffer
            string html = Encoding.UTF8.GetString(buffer, offset, count);

            // Use the regular expresion to replace URL with the
            // encrypt the query string 
            html = urlMatch.Replace(html, QueryStringMatchEvaluator);

            // Write the new response to the base stream
            byte[] buffer2 = Encoding.UTF8.GetBytes(html);
            outputStream.Write(buffer2, 0, buffer2.Length);
        }
    }
}
